﻿using System;
using System.ComponentModel.DataAnnotations;

namespace SQLLink.DomainClasses
{
    /// <summary>
    /// This is the GPRMC class
    /// It represent a GPRMC object
    /// </summary>
    public class GPRMC
    {
        private const int GprmcLength = 13; //Constant length
        public int GprmcId { get; set; } //Id property
        
        [Column("TimeStamp", Order = 2, TypeName = "datetime2")] 
        public DateTime TimeStamp { get; set; }                 //The GPRMC's TimeStamp
        public char Validity { get; set; }                      //The GPRMC's Validity
        public double Latitude { get; set; }                    //The GPRMC's Latitude
        public double Longitude { get; set; }                   //The GPRMC's Longitude
        public char NorthSouth { get; set; }                    //The GPRMC's NorthSouth label
        public char EastWest { get; set; }                      //The GPRMC's EastWest label
        public double SpeedKnots { get; set; }                  //The GPRMC's Speed in knots
        public double ReelSpeed { get; set; }                   //The GPRMC's Real speed
        public double Variation { get; set; }                   //The GPRMC's Variation
        public char VariationDir { get; set; }                  //The GPRMC's Variation Direction

        public virtual Bus ParentBus { get; set; }              //The parent bus for this

        /// <summary>
        /// GPRMC()
        /// This is the GPRMC empty constructor
        /// </summary>
        public GPRMC()
        {
        }
        
        /// <summary>
        /// GPRMC(String)
        /// This is the GPRMC specific constructor
        /// It set all the parameters according to the NMEA GPRMC string received
        /// </summary>
        /// <param name="str">the GPRMC string</param>
        public GPRMC(string str)
        {
            ParseFromString(str);
        }

        /// <summary>
        /// ParseFromString(string)
        /// This is the method called in the specific constructor
        /// </summary>
        /// <param name="receivedString"></param>
        public void ParseFromString(string receivedString)
        {
            //Splits the received strings with ','
            var splittedString = receivedString.Split(',');

            //Validates that the length of the string is good
            if (splittedString.Length != GprmcLength)
                return;

            //Iterates on the words
            for (var i = 0; i < splittedString.Length; i++)
            {
                //Replaces the '.' by ','
                splittedString[i] = splittedString[i].Replace('.', ',');
                
                //In case there are no values, adds a zero to prevent bugs
                if (splittedString[i] == "")
                {
                    splittedString[i] = "0";
                }
            }

            var year = int.Parse(splittedString[9].Substring(4, 2));        //Parses the year
            var month = int.Parse(splittedString[9].Substring(2, 2));       //Parses the month
            var day = int.Parse(splittedString[9].Substring(0, 2));         //Parses the day
            var seconds = int.Parse(splittedString[1].Substring(4, 2));     //Parses the seconds
            var minutes = int.Parse(splittedString[1].Substring(2, 2));     //Parses the minutes
            var hours = int.Parse(splittedString[1].Substring(0, 2));       //Parses the hours
            TimeStamp = new DateTime(year, month, day, hours, minutes, seconds); //Creates the timeStamp

            Validity = splittedString[2].ToCharArray()[0];  //Parses the validity

            //Parses the latitude
            Latitude = (splittedString[3][0] == '0') ? -double.Parse(splittedString[3]) : double.Parse(splittedString[3]);
            
            //Parses the longitude
            Longitude = (splittedString[5][0] == '0') ? -double.Parse(splittedString[5]) : double.Parse(splittedString[5]);
            NorthSouth = splittedString[4].ToCharArray()[0];        //Parses the NorthSouth label
            EastWest = splittedString[6].ToCharArray()[0];          //Parses the EastWest label
            SpeedKnots = double.Parse(splittedString[7]);           //Parses the Speed in knots
            ReelSpeed = double.Parse(splittedString[8]);            //Parses the Real speed
            Variation = double.Parse(splittedString[10]);           //Parses the Variation
            VariationDir = splittedString[11].ToCharArray()[0];     //Parses the Variation Direction
        }

        /// <summary>
        /// ToString()
        /// This is the ToString override method for a GPRMC object
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return Latitude + ", " + Longitude;
        }
    }
}
